﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;

using PEMS.Common;

namespace PEMS.Client
{
    class Client
    {
        private static System.Timers.Timer _pingTimer = new System.Timers.Timer();

        static void Main(string[] args)
        {
            Properties.Settings.Default.Save();
            _pingTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
            _pingTimer.Interval = 4000;
            _pingTimer.Start();
            _pingTimer.Enabled = false;

            fomenu();            
        }

        /// <summary>
        /// időzítés, hogy ne kelljen bizonyos tétlenség után ismét bejelentkezni
        /// ha a szerver közben egyszer is nem válaszol, akkor mindenképp login kell
        /// </summary>
        private static void OnTimedEvent(object source, ElapsedEventArgs e)
        {
            if (ClientController.instance.ping())
            {

            }
            else
            {
                header();
                _pingTimer.Enabled = false;
                Console.Write("\nUj bejelentkezes szukseges!");
            }
            GC.Collect();
        }

        /// <summary>
        /// metódusok visszatérő üzenetének megjelenítése
        /// stringekhez
        /// </summary>
        private static void display_message(string msg)
        {
            if (msg.Length == 0)
            {
                return;
            }
            Console.WriteLine("\n");
            Console.WriteLine(msg);
        }

        /// <summary>
        /// metódusok visszatérő üzenetének megjelenítése
        /// komm.msg -hez
        /// </summary>
        private static void display_message(List<string> msg)
        {
            if (msg.Count == 0)
            {
                return;
            }
            Console.WriteLine("\n");
            foreach (string s in msg)
                Console.WriteLine(s);
        }

        /// <summary>
        /// metódusok visszatérő üzenetének megjelenítése
        /// komm.rows -hoz
        /// </summary>
        private static void display_message(string header, string col1, string col2, List<List<string>> rows)
        {
            Console.WriteLine("\n" + header);           
            if (rows.Count == 0)
            {
                return;
            }
            else
            {
                Console.WriteLine("\n");
            }
            foreach (List<string> row in rows)
            {
                Console.Write(col1 + "\t{0}\n" + col2 + "\t{1}", row[0], row[1]);
            }
            Console.WriteLine("\n");
        }

        /// <summary>
        /// jogosultságfüggő menü kirajzolása
        /// </summary>
        private static void display_szemelyesMenu(ref int jog)
        {
            header();

            if (!ClientController.instance.kliensID.bools["belepve"])
                Console.WriteLine("1.  Bejelentkezes");
            else
            {
                Console.WriteLine("1.  Kijelentkezes");

                if (ClientController.instance.kliensID.strings["jogosultsag"] == "Hallgato")
                {
                    jog = 10;
                    Console.WriteLine("2.  Beiratkozas felevre"); // a féléves státusznyilatkozat a 3. iterációban fog kelleni
                    Console.WriteLine("3.  Kurzusjelentkezes");
                    Console.WriteLine("4.  Felvett kurzusok");
                    Console.WriteLine("5.  Vizsgajelentkezes");
                    Console.WriteLine("6.  Felvett vizsgák");
                    Console.WriteLine("7.  Vizsgaeredmények");
                    Console.WriteLine("8.  Felevek lekerdezese");
                    //                        Console.WriteLine("9.  Adatmodositas"); // 3. iterációban fog kelleni
                    
                }

                if (ClientController.instance.kliensID.strings["jogosultsag"] == "Oktato")
                {
                    jog = 20;
                    //                        Console.WriteLine("2.  Vizsga meghirdetese"); // 2. iterációban fog kelleni
                    Console.WriteLine("3.  Meghirdetett vizsgák (fix)");
                    Console.WriteLine("4.  Alairas beallitasa (fix)");
                    Console.WriteLine("5.  Vizsga ertekelese (fix)");
                    //                        Console.WriteLine("6.  Reszletes adatok lekerese"); // 3. iterációban fog kelleni
                }

                if (ClientController.instance.kliensID.strings["jogosultsag"] == "Administrator")
                {
                    jog = 30;
                    //                        Console.WriteLine("2.  Felhasznalo hozzaadasa"); // 2. iterációban fog kelleni
                    //                        Console.WriteLine("3.  Felhasznalo aktivalas / deaktivalas"); // 3. iterációban fog kelleni
                    Console.WriteLine("4.  Kurzuslista");
                    //                        Console.WriteLine("5.  Kurzus meghirdetese"); // 2. iterációban fog kelleni
                    //                        Console.WriteLine("6.  Oktato hozzarendelese kurzushoz"); // 2. iterációban fog kelleni
                    //                        Console.WriteLine("7.  Reszletes adatok lekerese"); // 3. iterációban fog kelleni

                }

            }
            Console.WriteLine("0.  Kilepes");            

            menualattisor();
        }

        /// <summary>
        /// jegy értékelésekor felugró oktatói almenü
        /// </summary>
        private static void display_vizsgaErtekelesMenu()
        {
            Console.WriteLine("\nValasszon egy osztalyzatot:\n");
            Console.WriteLine("1. Elegtelen");
            Console.WriteLine("2. Elegseges");
            Console.WriteLine("3. Kozepes");
            Console.WriteLine("4. Jo");
            Console.WriteLine("5. Jeles");
            Console.WriteLine("6. Nem jelent meg");
            Console.WriteLine("0. Vissza");
        }

        /// <summary>
        /// felhasználói műveletek megerősítése
        /// </summary>
        private static bool valasztasMegerositese(string szoveg, string megszakitSzoveg)
        {
            string valasz;
            do {
                display_message(szoveg + " (I / N)");
                valasz = Console.ReadLine().ToUpper();
                if ((valasz != "I") && (valasz != "N"))
                {
                    display_message("Nincs ilyen valaszlehetoseg, probalja ujra!\n");
                }
            } while ((valasz != "I") && (valasz != "N"));
            if (valasz == "N")
            {
                display_message("Felhasznaloi megszakitas. Nem tortent " + megszakitSzoveg + "!");
            }
            return (valasz == "I");
        }

        /// <summary>
        /// félévlista megjelenítése
        /// </summary>
        private static void felevLista(bool aktualis)
        {
            N_1 komm_lekerdez = ClientController.instance.getFelevList(aktualis);
            display_message("Felevek listaja: ", "Felev azonositoja: ", "Felev megnevezese: ", komm_lekerdez.rows);    
        }

        /// <summary>
        /// kurzuslista megjelenítése
        /// </summary>
        private static void kurzusLista()
        {
            N_1 komm = ClientController.instance.getKurzusList("12/13");
            display_message("Kurzuslista: ", "Kurzus kódja: ", "Megnevezese: ", komm.rows);
        }
                
        /// <summary>
        /// a főmenü
        /// </summary>
        public static void fomenu(){
            int selector = -1;
            int jog = 0;
            bool exit = false;
            bool good = false;            
            do
            {
                display_szemelyesMenu(ref jog);
                good=int.TryParse(Console.ReadLine(), out selector);
                if (good)
                {
                    if (selector > 1)
                        selector += jog;
                    switch (selector)
                    {
                        case 1: // Logon - Logoff - Mindenki
                            if (!ClientController.instance.kliensID.bools["belepve"])
                                logon();
                            else
                                logoff();                            
                            break;

                        case 12: // Beiratkozás félévre - Hallgato
                            {
                                bool aktualis = true;
                                felevLista(aktualis);                                
                                N_1 komm_lekerdez = ClientController.instance.getFelevFelveve("12/13", ClientController.instance.kliensID.strings["userNev"]);
                                display_message(komm_lekerdez.msg);
                                if ((!komm_lekerdez.bools["beiratkozott"]) && (!komm_lekerdez.bools["hiba"]))
                                {
                                    if (valasztasMegerositese("Biztosan beiratkozik?", "beiratkozas"))
                                    {
                                        N_1 komm = ClientController.instance.BeiratkozasFelevre("12/13", ClientController.instance.kliensID.strings["userNev"]);
                                        display_message(komm.msg);
                                    }
                                }
                                break;
                            }

                        case 13: // Kurzusjelentkezés - Hallgato
                            kurzusLista();
                            {
                                N_1 komm_lekerdez = ClientController.instance.getKurzusFelveve("12/13", "rfke_kurzus", ClientController.instance.kliensID.strings["userNev"]);
                                display_message(komm_lekerdez.msg);
                                if ((!komm_lekerdez.bools["felvette"]) && (!komm_lekerdez.bools["hiba"]))
                                {
                                    if (valasztasMegerositese("Biztosan felveszi a kurzust?", "kurzusfelvetel"))
                                    {
                                        N_1 komm = ClientController.instance.KurzusraFeliratkozik("12/13", "rfke_kurzus");
                                        display_message(komm.msg);
                                    }
                                }
                                break;
                            }

                        case 14: // Felvett kurzusok - Hallgato
                            {
                                N_1 komm = ClientController.instance.getFelvettKurzus("12/13", ClientController.instance.kliensID.strings["userNev"]);
                                display_message("Felvett kurzusok: ", "Kurzus megnevezese: ", "Felvetelek szama: ", komm.rows);
                                display_message(komm.msg);
                                break;
                            }

                        case 15:  // 15 a vizsgajelentkezés, lásd lejjebb
//                        case 16:
                        case 23: // Meghirdetett vizsgák
                            {
                                N_1 komm = ClientController.instance.getKurzusVizsgaIdopontList("12/13", "rfke_kurzus");
                                display_message("Meghirdetett vizsgaidopontok: ", "Idopont: ", "Max letszam: ", komm.rows);
                                display_message(komm.msg);                                
                            }
                            if (selector == 15) // Ez az elágazás a vizsgajelentkezés
                            {
                                if (valasztasMegerositese("Biztosan jelentkezik a vizsgara?", "jelentkezes"))
                                {
                                    N_1 komm = ClientController.instance.VizsgaIdopontraFeliratkozas("12/13", "rfke_kurzus", "1");
                                    display_message(komm.msg);
                                }
                            }
                            break;

                        case 16: // Felvett vizsgák - Hallgato
                            {
                                N_1 komm = ClientController.instance.getFelvettVizsga("12/13", ClientController.instance.kliensID.strings["userNev"]);
                                display_message("Felvett vizsgak: ", "Tantargy neve: ", "Idopont: ", komm.rows);
                                display_message(komm.msg);
                                break;
                            }

                        case 17: // Vizsgaeredmények - Hallgato
                            {
                                N_1 komm = ClientController.instance.getVizsgaEredmenyek("12/13", ClientController.instance.kliensID.strings["userNev"]);
                                display_message("Vizsgaeredmenyek: ", "Tantargy neve: ", "Erdemjegy: ", komm.rows);
                                display_message(komm.msg);
                                break;
                            }

                        case 18: // Félévek
                            {
                                N_1 komm = ClientController.instance.getFelevInfo(ClientController.instance.kliensID.strings["userNev"]);
                                display_message("Informacio a felevekrol: ", "Szemeszter: ", "Statusz: ", komm.rows);
                                display_message(komm.msg);
                                break;
                            }

                        case 24: // Aláírás beállítása - Oktato
                            {
                                N_1 komm_lekerdez = ClientController.instance.getAlairasBeallitva("12/13", "rfke_kurzus", "h1");
                                display_message(komm_lekerdez.msg);
                                if ((!komm_lekerdez.bools["alairva"]) && (!komm_lekerdez.bools["hiba"]))
                                {
                                    if (valasztasMegerositese("Biztosan megadja az alairast?", "alairas beallitas"))
                                    {
                                        N_AlairasBeallitas komm = ClientController.instance.AlairasBeallitas("12/13", "rfke_kurzus", "h1", AlairasEnum.alairva);
                                        display_message(komm.msg);
                                    }
                                }
                                break;
                            }

                        case 25: // Vizsgajegy beírása - Oktato
                            {
                                //vizsgáljuk, írhatunk-e jegyet, ehhez megkérdezzük a kontrollert
                                N_1 komm1 = ClientController.instance.VizsgaJegyEllenorzes("12/13", "rfke_kurzus", "1", "h1");
                                if (komm1.bools["vizsgaJegyAdhato"])
                                {
                                    display_vizsgaErtekelesMenu();                                    

                                    int jegy = 0;
                                    ErdemjegyEnum erdemjegy = ErdemjegyEnum.meg_nem_vizsgazott;
                                    if (int.TryParse(Console.ReadLine(), out jegy))
                                    {
                                        switch (jegy)
                                        {
                                            case 1:
                                                erdemjegy = ErdemjegyEnum.elegtelen;
                                                break;
                                            case 2:
                                                erdemjegy = ErdemjegyEnum.elegseges;
                                                break;
                                            case 3:
                                                erdemjegy = ErdemjegyEnum.kozepes;
                                                break;
                                            case 4:
                                                erdemjegy = ErdemjegyEnum.jo;
                                                break;
                                            case 5:
                                                erdemjegy = ErdemjegyEnum.jeles;
                                                break;
                                            case 6:
                                                erdemjegy = ErdemjegyEnum.nem_jelent_meg;
                                                break;
                                            case 0:
                                                display_message("Vissza a fomenube - folytatashoz nyomjon entert");
                                                break;
                                            default:
                                                display_message("Nincs ilyen menupont!");
                                                break;
                                        }
                                    }
                                    else
                                    {
                                        display_message("Nincs ilyen menupont!");
                                    }
                                    if ((jegy > 0) && (jegy < 7))
                                    {
                                        if (valasztasMegerositese("Biztosan beirja az osztalyzatot? (" + erdemjegy + ")", "az ertekeles"))
                                        {
                                            N_VizsgaJegyBeiras komm = ClientController.instance.VizsgaJegyBeiras("12/13", "rfke_kurzus", "1", "h1", erdemjegy);
                                            display_message(komm.msg);
                                        }
                                    }
                                }
                                else
                                {
                                    display_message(komm1.msg);
                                }
                                break;
                            }

                        case 34: // Kurzuslista - Admin
                            kurzusLista();
                            break;                            

                        case 0:
                            exit = true;
                            break;

                        default:
                            break;
                    }
                    if ((!exit) && (selector != 1))
                    {
                        Console.ReadLine();
                    }
                }
                else
                {
                    display_message("Nincs ilyen menupont!");
                }


            } while (!exit);
            Console.WriteLine("exit");
        }

        /// <summary>
        /// kijelentkezés
        /// </summary>
        static void logoff()
        {
            _pingTimer.Enabled = false;
            ClientController.instance.logoff();
        }

        /// <summary>
        /// bejelentkezés
        /// </summary>
        static void logon()
        {
            header();
            Console.WriteLine("logon to server: ");
            Console.Write("\nConnect to server... ");

            if (ClientController.instance.open())
            {
                Console.WriteLine("ok");
                Console.ForegroundColor = ConsoleColor.Green;
                Console.Write("\nusername: ");
                Console.ForegroundColor = ConsoleColor.Gray;
                string u = Console.In.ReadLine();
                Console.Write("password: ");
                string p = getPassword();
                Console.Write("\nlogon... ");

                if (ClientController.instance.logon(u, p))
                {
                    _pingTimer.Enabled = true;
                }
                else
                {
                    display_message(ClientController.instance.kliensID.msg);
                    Console.ReadLine();
                }
            }
            else
            {
                Console.WriteLine("\nKapcsolodasi hiba! Enter a folytatashoz...");
                Console.ReadLine();
            }
        }

        /// <summary>
        /// menü alá elválasztás
        /// </summary>
        public static void menualattisor()
        {
            int consoleWidth = Console.WindowWidth;

            //Console.WriteLine("");

            for (int i = 0; i < consoleWidth; i++)
            {
                Console.Write("-");
            }
        }

        /// <summary>
        /// konzok ablak első két sora
        /// </summary>
        public static void header()
        {
            int consoleWidth = Console.WindowWidth;
            Console.Clear();
            Console.SetCursorPosition(0, 0);
            Console.Write("PEMS - Kliens");

            if (ClientController.instance.kliensID.bools["belepve"])
            {
                Console.SetCursorPosition(8, 0);
                Console.Write("ID: {0}", ClientController.instance.kliensID.strings["id"]);
                Console.SetCursorPosition(64, 0);
            
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.Write("user: {0}", ClientController.instance.kliensID.strings["userNev"]);
                Console.ForegroundColor = ConsoleColor.Gray;
            }
            Console.WriteLine("");

            for (int i = 0; i < consoleWidth; i++)
            {
                Console.Write("-");
            }
        }

        /// <summary>
        /// jelszó bekérés, úgy hogy ne látszódjanak a beírt karakterek
        /// </summary>
        /// <returns>a jelszó</returns>
        public static string getPassword()
        {
            string password = "";
            ConsoleKeyInfo info = Console.ReadKey(true);
            while (info.Key != ConsoleKey.Enter)
            {
                if (info.Key != ConsoleKey.Backspace)
                {
                    password += info.KeyChar;
                    info = Console.ReadKey(true);
                }
                else if (info.Key == ConsoleKey.Backspace)
                {
                    if (!string.IsNullOrEmpty(password))
                    {
                        password = password.Substring
                        (0, password.Length - 1);
                    }
                    info = Console.ReadKey(true);
                }
            }
            for (int i = 0; i < password.Length; i++)
                Console.Write("*");
            return password;
        }
        
    }
}
